package it.iaproject.ui;

import it.iaproject.Cell;
import it.iaproject.Map;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.io.File;
import java.io.IOException;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class MapPanel extends JPanel {

	public static final int PREFERRED_GRID_CELL_SIZE_PIXELS = 40;

	private Image marioImage;
	private Image peachImage;
	private Image goombaImage;
	private Image bridge401Image;
	private Image bridge402Image;
	private Image bridgeOrizImage;
	private Image bridgeVertImage;
	private Image winImage;
	private Image markerImage;

	private boolean alreadyInitialized;

	private Cell modifiedCell;

	private Map map;

	public MapPanel(Map m) {
		try {
			this.map = m;
			alreadyInitialized = false;
			int preferredWidth = map.getDim() * PREFERRED_GRID_CELL_SIZE_PIXELS;
			int preferredHeight = map.getDim() * PREFERRED_GRID_CELL_SIZE_PIXELS;
			setPreferredSize(new Dimension(preferredWidth, preferredHeight));
			

			marioImage = ImageIO.read(new File("res/mario.png"));
			peachImage = ImageIO.read(new File("res/peach.png"));
			goombaImage = ImageIO.read(new File("res/goomba.png"));
			bridge401Image = ImageIO.read(new File("res/bridge401.png"));;// \
			bridge402Image = ImageIO.read(new File("res/bridge402.png"));;// /
			bridgeOrizImage = ImageIO.read(new File("res/bridge40oriz.png"));
			bridgeVertImage = ImageIO.read(new File("res/bridge40vert.png"));
			winImage = ImageIO.read(new File("res/win.png"));
			markerImage = ImageIO.read(new File("res/marked.png"));

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void paintComponent(Graphics g) {
		// Important to call super class method
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		int width = getWidth() / map.getDim();
		int height = getHeight() / map.getDim();

//		if (!alreadyInitialized || modifiedCell == null) {
//			super.paintComponent(g);
			// Clear the board
			g.clearRect(0, 0, getWidth(), getHeight());
			// Draw the grid
			for (int i = 0; i < map.getDim(); i++) {
				for (int j = 0; j < map.getDim(); j++) {
					// Upper left corner of this terrain rect
					updateCell(i, j, width, height, g2);

				}
			}
//			alreadyInitialized = true;
//		} else {
//			for (int j = 0; j < map.getDim(); j++) {
//				updateCell(0, j, width, height, g2);
//			}
//
//			Vector<Cell> neighbours = map.neighbour8Cells(modifiedCell);
//			updateCell(modifiedCell.getRow(), modifiedCell.getCol(), width, height, g2);
//
//			for (Cell neighbour : neighbours)
//				updateCell(neighbour.getRow(), neighbour.getCol(), width, height, g2);
//
//		}
		//		JOptionPane.showConfirmDialog(this, "mfp", "", JOptionPane.INFORMATION_MESSAGE, JOptionPane.CANCEL_OPTION, winImage);
	}


	public void updateCell(int i, int j, int width, int height, Graphics2D g2) {
		int y = i * height;
		int x = j * width;
		Integer status = map.getCell(i, j).getStatus();

		if (status == Cell.FREE) {
			g2.setColor(Ui.GREEN);
			g2.fillRect(x, y, width, height);
		}

		if (status == Cell.RIVER) {
			g2.setColor(Ui.BLU);
			g2.fillRect(x, y, width, height);
		}

		if (status == Cell.BRIDGE || status == Cell.MARIOONTHEBRIDGE) {
			g2.setColor(Ui.BLU);
			g2.fillRect(x, y, width, height);
			Vector<Cell> neighbour = new Vector<Cell>();

			if (i != 0) {neighbour.add(map.getCell(i-1, j));}
			if (i != map.getDim()-1) {neighbour.add(map.getCell(i+1, j));}
			if (j != 0) {neighbour.add(map.getCell(i, j-1));}
			if (j != map.getDim()-1) {neighbour.add(map.getCell(i, j+1));}


			Vector<Cell> riverCells = new Vector<Cell>();
			for (Cell c : neighbour)
				if (c.getStatus() == Cell.RIVER || c.getStatus() == Cell.BRIDGE)
					riverCells.add(c);

					if (riverCells.size()>2) System.out.println("ERRR troppa acqua!");//TODO ERRROOOORRR

					if (riverCells.size() == 2) {
						if (riverCells.get(0).getCol() == riverCells.get(1).getCol()) {
							g2.drawImage(bridgeOrizImage, x, y, null);
						} else 	if (riverCells.get(0).getRow() == riverCells.get(1).getRow()) {
							g2.drawImage(bridgeVertImage, x, y, null);
						} else if ((riverCells.get(0).getCol() < j && riverCells.get(1).getRow() > i) ||
								(riverCells.get(0).getRow() > i && riverCells.get(1).getCol() < j) ||
								(riverCells.get(0).getCol() > j && riverCells.get(1).getRow() < i) ||
								(riverCells.get(0).getRow() < i && riverCells.get(1).getCol() > j)) {
							g2.drawImage(bridge402Image, x, y, null);
						} else {
							g2.drawImage(bridge401Image, x, y, null);
						}
					}


					if (riverCells.size() == 1) {
						if ((riverCells.get(0).getCol() == 1 && j == 0) || (riverCells.get(0).getCol() == map.getDim()-2 && j == map.getDim()-1))
							g2.drawImage(bridgeVertImage, x, y, null);

						if ((riverCells.get(0).getRow() == 1 && i == 0) || (riverCells.get(0).getRow() == map.getDim()-2 && i == map.getDim()-1))
							g2.drawImage(bridgeOrizImage, x, y, null);
					}
		}

		if (status == Cell.PEACH) {
			g2.setColor(Ui.GREEN);
			g2.fillRect(x, y, width, height);
			g2.drawImage(peachImage, x, y, null);
		}

		if (status == Cell.ENEMY) {
			g2.setColor(Ui.GREEN);
			g2.fillRect(x, y, width, height);
			g2.drawImage(goombaImage, x, y, null);
		}

		if (status == Cell.MARIO) {
			g2.setColor(Ui.GREEN);
			g2.fillRect(x, y, width, height);
			g2.drawImage(marioImage, x, y, null);
		}

		if (status == Cell.MARIOONTHEBRIDGE) {
			g2.drawImage(marioImage, x, y, null);
		}

		if (status == Cell.WIN) {
			g2.setColor(Ui.GREEN);
			g2.fillRect(x, y, width, height);
			g2.drawImage(winImage, x, y, null);
		}

		/////print dinstance
		if(map.getCell(i, j).getDistance() != -1) {
			g2.setPaint(Color.BLACK);
			g2.setFont(new Font("Serif", Font.PLAIN, 10));
			String s = new Double(map.getCell(i, j).getDistance()).toString();
			g2.drawString(s, x, y + height);
		}

		if (map.ia.visited.contains(map.getCell(i, j))) {
			g2.drawImage(markerImage, x, y, null);
		}
	}

	public boolean isAlreadyInitialized() {
		return alreadyInitialized;
	}

	public void setAlreadyInitialized(boolean alreadyInitialized) {
		this.alreadyInitialized = alreadyInitialized;
	}

	public Cell getModifiedCell() {
		return modifiedCell;
	}

	public void setModifiedCell(Cell modifiedCell) {
		this.modifiedCell = modifiedCell;
	}

}
